package com.dmitriyp.movie.view;

import java.util.List;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import com.dmitriyp.movie.EntityObserver;
import com.dmitriyp.movie.EntityObserver.MovieChangeListener;
import com.dmitriyp.movie.dao.IMovieManager;
import com.dmitriyp.movie.dao.MovieManagerFactory;
import com.dmitriyp.movie.dao.Order;
import com.dmitriyp.movie.dao.Order.Type;
import com.dmitriyp.movie.editor.MovieEditor;
import com.dmitriyp.movie.editor.MovieEditorInput;
import com.dmitriyp.movie.mapping.Movie;
import com.dmitriyp.movie.mapping.MovieDBConstants;

public class MovieView extends ViewPart {

	private IMovieManager movieManager;
	private MovieEditor editor;
	private MovieListPart movieListPart;

	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		movieManager = new MovieManagerFactory().createMovieManager();
		new Thread() {
			@Override
			public void run() {
				Display.getDefault().asyncExec(new Runnable() {

					@Override
					public void run() {
						movieListPart.setValue(movieManager.listAll(new Order(
								Type.ASC,
								MovieDBConstants.MOVIE_TITLE_FIELD)));
					}
				});
			}
		}.start();
		EntityObserver.getInstance().addListener(new MovieChangeListener() {

			@Override
			public void update(Movie movie) {
			}

			@Override
			public void delete(Movie movie) {
			}

			@Override
			public void add(Movie movie) {
				movieListPart.add(movie);
			}
		});
	}

	@Override
	public void createPartControl(Composite parent) {
		this.createToolBar();

		GridLayout layout = new GridLayout(1, true);
		parent.setLayout(layout);

		movieListPart = new MovieListPart(parent);
		movieListPart.setSelectionListener(new IMoviePartListener() {

			@Override
			public void selected(Movie movie) {
				openMovie(movie);
			}

			@Override
			public void searchByStar(String star) {
				List<Movie> result = star.isEmpty() ? movieManager
						.listAll(new Order(Type.ASC,
								MovieDBConstants.MOVIE_TITLE_FIELD))
						: movieManager.filterByStar(star);
				movieListPart.setValue(result);
			}

			@Override
			public void searchByTitle(String title) {
				List<Movie> result = title.isEmpty() ? movieManager
						.listAll(new Order(Type.ASC,
								MovieDBConstants.MOVIE_TITLE_FIELD))
						: movieManager.filter(title);
				movieListPart.setValue(result);
			}
		});
	}

	private void createToolBar() {
		// Button for Add movie action
		getViewSite().getActionBars().getToolBarManager().add(new Action() {

			@Override
			public ImageDescriptor getImageDescriptor() {
				return ImageDescriptor.createFromImage(PlatformUI
						.getWorkbench().getSharedImages()
						.getImage(ISharedImages.IMG_OBJ_ELEMENT));
			}

			@Override
			public void run() {
				openMovie(new Movie());
			}
		});
		// Button for Delete movie action
		getViewSite().getActionBars().getToolBarManager().add(new Action() {

			@Override
			public ImageDescriptor getImageDescriptor() {
				return ImageDescriptor.createFromImage(PlatformUI
						.getWorkbench().getSharedImages()
						.getImage(ISharedImages.IMG_TOOL_DELETE));
			}

			@Override
			public void run() {
				if (movieListPart.getSelection() == null)
					return;
				deleteMovie(movieListPart.getSelection());
			}
		});

	}

	private void openMovie(Movie movie) {
		if (movie.getId() != null) {
			Movie instance = movieManager.get(movie.getId());
			if (instance != null)
				movie = instance;
		}
		boolean isVisible = getViewSite().getWorkbenchWindow().getActivePage().isPartVisible(editor);
		if (editor != null && isVisible) {
			editor.showEditorInput(new MovieEditorInput(movie));
			return;
		}
		try {
			editor = (MovieEditor) getViewSite().getWorkbenchWindow()
					.getActivePage()
					.openEditor(new MovieEditorInput(movie), MovieEditor.ID);
		} catch (PartInitException e) {
			e.printStackTrace();
		}
	}

	private void deleteMovie(Movie movie) {
		if (movieManager.delete(movie)) {
			movieListPart.delete(movie);
			if (getViewSite().getWorkbenchWindow().getActivePage()
					.closeEditor(editor, false)) {
				editor = null;
			}
		}
	}

	@Override
	public void setFocus() {

	}

}
